#include "interaction_manager.h"
#include "manager_queue_comm.h"
#include "module_queue_struct.h"
#include "wiota_app.h"
#include <rtthread.h>
#define DBG_ENABLE
#define DBG_SECTION_NAME "in_mn"
#include "uc_log.h"

/**
 * @brief IoTE状态更新信息释放
 *
 * @param state IoTE状态更新信息结构体指针
 */
void mng_ul_iote_state_free(mng_ul_iote_state_t *state)
{
    if (RT_NULL != state)
    {
        if (state->head.dest_addr != RT_NULL)
        {
            rt_free(state->head.dest_addr);
        }
    }
}

/**
 * @brief 用户上行透传数据释放
 *
 * @param user_data 用户上行数据结构体指针
 */
void mng_ul_userdata_free(mng_ul_userdata_t *user_data)
{
    if (RT_NULL != user_data)
    {
        if (user_data->head.dest_addr != RT_NULL)
        {
            rt_free(user_data->head.dest_addr);
        }
    }
}

/**
 * @brief 网络下行透传数据释放
 *
 * @param net_data 网络下行透传数据指针
 */
void net_dl_userdata_free(net_dl_userdata_t *net_data)
{
    if (RT_NULL != net_data)
    {
        if (RT_NULL != net_data->head.dest_addr)
        {
            rt_free(net_data->head.dest_addr);
        }

        if (RT_NULL != net_data->broadcast_data)
        {
            rt_free(net_data->broadcast_data);
        }

        if (RT_NULL != net_data->unicast_data)
        {
            rt_free(net_data->unicast_data);
        }
        rt_free(net_data);
    }
}

/**
 * @brief 透传数据释放
 *
 * @param net_data 透传数据指针
 */
void net_dl_transparent_data_free(net_dl_transparent_data_t *net_data)
{
    if (RT_NULL != net_data)
    {
        if (RT_NULL != net_data->transparent_data)
        {
            rt_free(net_data->transparent_data);
        }
        rt_free(net_data);
    }
}

/**
 * @brief 发送命令和数据到WIoTa APP线程
 *
 * @param module         源线程模块
 * @param cmd            WIoTa APP命令
 * @param order_business 顺序发送业务
 * @param src_address    源地址（网关默认地址）
 * @param dest_address   要发送目标IoTE的设备地址
 * @param data           发送数据指针
 * @param data_len       发送数据长度
 * @param func           发送结果回调
 * @return int           0表示成功，非0表示失败
 */
int manager_send_to_wiota(int module,
                          unsigned int cmd,
                          unsigned int order_business,
                          unsigned int src_address,
                          unsigned int dest_address,
                          void *data,
                          int data_len,
                          wiota_msg_exec_result func)
{
    mng_to_wiota_data_t *page = rt_malloc(sizeof(mng_to_wiota_data_t));
    RT_ASSERT(page);
    rt_memset(page, 0, sizeof(mng_to_wiota_data_t));

    page->src_module = (unsigned char)(module & 0xFF);
    page->head.id = dest_address;
    page->head.result = WIOTA_SEND_DEFAULT;
    page->head.result_function = func;
    page->head.cmd = cmd;
    page->head.src_address = src_address;
    page->data = data;
    page->data_len = data_len;
    page->order_business = order_business;

    if (0 != module_queue_communication(get_wiota_app_queue(),
                                        module,
                                        WIOTA_APP_MODULE,
                                        cmd,
                                        (void *)page))
    {
        rt_free(page);
        TRACE_E("manager_send_to_wiota error\n");
        return 1;
    }
    return 0;
}

/**
 * @brief 网关管理线程到WIoTa APP线程数据释放
 *
 * @param to_wiota_data 网关管理线程到WIoTa APP线程数据结构体指针
 */
void manager_to_wiota_data_free(mng_to_wiota_data_t *to_wiota_data)
{
    if (RT_NULL != to_wiota_data->head.result_function)
    {
        to_wiota_data->head.result_function(to_wiota_data);
    }
    else
    {
        if (RT_NULL != to_wiota_data)
        {
            if (RT_NULL != to_wiota_data->data)
            {
                rt_free(to_wiota_data->data);
            }
            rt_free(to_wiota_data);
        }
    }
}

/**
 * @brief WIoTa APP线程到网关管理线程数据释放
 *
 * @param to_mng_data WIoTa APP线程到网关管理线程数据结构体指针
 */
void wiota_to_manager_data_free(wiota_to_mng_data_t *to_mng_data)
{
    if (RT_NULL != to_mng_data)
    {
        if (RT_NULL != to_mng_data->data)
        {
            rt_free(to_mng_data->data);
        }
        rt_free(to_mng_data);
    }
}

/**
 * @brief 十六进制输出数据
 *
 * @param data     数据指针
 * @param data_len 数据长度
 */
void manager_printf_data_hex(unsigned char *data, int data_len)
{
    for (int i = 0; i < data_len; i++)
    {
        if (i != 0 && i % 16 == 0)
        {
            rt_kprintf("\n");
        }
        rt_kprintf("%02x ", data[i]);
    }
    rt_kprintf("\n");
}